package vn.com.bookstore.controller;

import java.util.HashSet;
import java.util.Set;
import java.util.regex.Pattern;

import javax.servlet.ServletRequest;

import net.tanesha.recaptcha.ReCaptchaImpl;
import net.tanesha.recaptcha.ReCaptchaResponse;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.GrantedAuthorityImpl;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import vn.com.bookstore.domain.model.Account;
import vn.com.bookstore.model.vo.CustomerVO;
import vn.com.bookstore.model.vo.ErrorJson;
import vn.com.bookstore.service.CustomerService;
import vn.com.bookstore.utils.DataHelper;
import vn.com.bookstore.utils.GenerateMD5;

@SuppressWarnings("deprecation")
@Controller
public class LoginController {

	private static final Logger logger = LoggerFactory
			.getLogger(LoginController.class);
	private static final String PHONE_PATTERN = "[0-9]+";
	private static final String EMAIL_PATTERN = "^[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-]+)*@"
			+ "[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$";
	
	@Value("${recapchar.private.key}")
	public String privateKey;
	
	@Value("${recapchar.public.key}")
	public String publicKey;
	
	@Autowired
	private CustomerService customerService;

	@Autowired
	@Qualifier("authenticationManager")
	protected AuthenticationManager authenticationManager;

	@RequestMapping(value = "/online/login_security_check", method = RequestMethod.POST)
	public @ResponseBody
	ErrorJson login(Model model, @RequestParam("username") String username,
			@RequestParam("password") String password) {
		ErrorJson errorJson = new ErrorJson();
		errorJson.setValidate(false);
		if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) {
			errorJson
					.setErrorPass("Cần nhập thông tin tên đăng nhập và mật khẩu");
			errorJson.setValidate(true);
			return errorJson;
		}

		try {
			Set<GrantedAuthority> dbAuthsSet = new HashSet<GrantedAuthority>();
			dbAuthsSet.add(new GrantedAuthorityImpl(
					DataHelper.UserRole.ROLE_FOR_WEBSITE.getCode()));
			User user = new User(username, password, dbAuthsSet);
			UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(
					user, password);
			Authentication authResult = authenticationManager
					.authenticate(authRequest);
			SecurityContextHolder.getContext().setAuthentication(authResult);
		} catch (AuthenticationException e) {
			logger.info("Check login: " + e.getMessage());
			errorJson.setErrorPass("Tên đăng nhập hoặc mật khẩu chưa đúng");
			errorJson.setValidate(true);
			return errorJson;
		}
		return errorJson;
	}

	@RequestMapping(value = "/online/register-account", method = RequestMethod.GET)
	public String openRegisterAccount(Model model) {
		CustomerVO customerVO = new CustomerVO();
		model.addAttribute("customerVO", customerVO);
		model.addAttribute("recapcharError", null);
		model.addAttribute("errorObj", new ErrorJson());
		return "website/account/registerAccount";
	}

	@RequestMapping(value = "/online/registeredAccount", method = RequestMethod.POST)
	public String registerAccount(Model model,
			@ModelAttribute("customerVO") CustomerVO customerVO,
			@RequestParam("recaptcha_challenge_field") String challangeField,
			@RequestParam("recaptcha_response_field") String responseField,
			ServletRequest servletRequest) {
		String remoteAddress = servletRequest.getRemoteAddr();
		ReCaptchaImpl reCaptchaService = new ReCaptchaImpl();
		ErrorJson errorJson = new ErrorJson();
		errorJson.setValidate(true);
		// TODO change with the address of the web-site
		reCaptchaService.setPrivateKey(privateKey);
		reCaptchaService.setPublicKey(publicKey);
		ReCaptchaResponse reCaptchaResponse = reCaptchaService.checkAnswer(
				remoteAddress, challangeField, responseField);

		if (!reCaptchaResponse.isValid()) {
			model.addAttribute("recapcharError", "Ký tự xác nhận chưa đúng!");
			return "website/account/registerAccount";
		}
		Pattern phonePattern = Pattern.compile(PHONE_PATTERN);
		Pattern emailPattern = Pattern.compile(EMAIL_PATTERN);
		if (StringUtils.isEmpty(customerVO.getFirstname())
				|| StringUtils.isEmpty(customerVO.getLastname())
				|| StringUtils.isEmpty(customerVO.getMiddle())) {
			errorJson.setErrorName("Cần nhập thông tin");
			errorJson.setValidate(false);
		}
		if (StringUtils.isEmpty(customerVO.getBirthday())) {
			errorJson.setErrorDOB("Cần nhập thông tin");
			errorJson.setValidate(false);
		} else if (!customerService.validateDate(customerVO.getBirthday())) {
			errorJson.setErrorDOB("Ngày sinh không đúng (dd/MM/yyyy)");
			errorJson.setValidate(false);
		}
		if (StringUtils.isEmpty(customerVO.getPhone())) {
			errorJson.setErrorPhone("Cần nhập thông tin");
			errorJson.setValidate(false);
		} else if (!phonePattern.matcher(customerVO.getPhone()).matches()) {
			errorJson.setErrorPhone("Số điện thoại không hợp lệ!");
			errorJson.setValidate(false);
		}
		if (StringUtils.isEmpty(customerVO.getEmail())) {
			errorJson.setErrorMail("Cần nhập thông tin");
			errorJson.setValidate(false);
		} else if (!emailPattern.matcher(customerVO.getEmail()).matches()) {
			errorJson.setErrorMail("Email không hợp lệ (VD: abc@example.com)!");
			errorJson.setValidate(false);
		}
		if (StringUtils.isEmpty(customerVO.getUsername())) {
			errorJson.setErrorUsername("Cần nhập thông tin");
			errorJson.setValidate(false);
		} else if (customerService.checkExistedUsername(customerVO
				.getUsername())) {
			errorJson
					.setErrorUsername("Tên đăng nhập không hợp lệ hoặc đã tồn tại!");
			errorJson.setValidate(false);
		}

		if (!errorJson.isValidate()) {
			model.addAttribute("errorObj", errorJson);
			return "website/account/registerAccount";
		}

		Account account = new Account();
		account.setEmail(customerVO.getEmail());
		account.setUsername(customerVO.getUsername());
		account.setPassword(GenerateMD5.MD5(customerVO.getPassword()));
		account.setActive(true);
		account.setTypeAccountId(customerService
				.getAccountTypeIdByName(DataHelper.UserRole.ROLE_FOR_WEBSITE
						.getCode()));
		int account_id = customerService.createAccount(account);
		customerVO.setAccountId(account_id);
		try {
			customerService.createNewCustomer(customerVO);
		} catch (Exception e) {
			logger.info("registerAccount: " + e.getMessage());
			customerService.deleteAccountById(account_id);
			model.addAttribute("successMessage", "Hệ thống bị lỗi! Xin hãy đăng ký lại trong giây lát!");
			return "website/account/registerAccount";
		}
		return "redirect:home";
	}

	
}
